home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 May: Tool Chest / Developer CD Series Tool Chest (Apple Computer)(May 1999).iso / Tool Chest / Development Kits / MPW etc / MPW-GM / MPW / Examples / AExamples / SampleMisc.a < prev   
Encoding:
Text File  |  1998-12-03  |  31.6 KB  |  840 lines  |  [TEXT/MPS ]

  1. *
  2. *    Apple Macintosh Developer Technical Support
  3. *
  4. *    MultiFinder-Aware Simple Sample Application
  5. *
  6. *    Sample
  7. *
  8. *    SampleMisc.a    -    Assembler Source
  9. *
  10. *    Copyright © 1989,1993 Apple Computer, Inc.
  11. *    All rights reserved.
  12. *
  13. *    Versions:    
  14. *        1.00            08/88
  15. *        1.01            11/88
  16. *        1.02            04/89    MPW 3.1
  17. *        1.03            02/90    MPW 3.2
  18. *        1.04            11/93    MPW 3.3.1 (ETO 13)
  19. *        1.05            1/96    MPW 3.4 (ETO 20)
  20. *
  21. *    Components:
  22. *        Sample.a        Feb. 1, 1990
  23. *        Sample.inc1.a    Feb. 1, 1990
  24. *        SampleMisc.a    Feb. 1, 1990
  25. *        Sample.r        Feb. 1, 1990
  26. *        Sample.h        Feb. 1, 1990
  27. *        Sample.make        Feb. 1, 1990
  28. *
  29. *    Sample is an example application that demonstrates how to
  30. *    initialize the commonly used toolbox managers, operate 
  31. *    successfully under MultiFinder, handle desk accessories, 
  32. *    and create, grow, and zoom windows.
  33. *
  34. *    It does not by any means demonstrate all the techniques 
  35. *    you need for a large application. In particular, Sample 
  36. *    does not cover exception handling, multiple windows/documents, 
  37. *    sophisticated memory management, printing, or undo. All of 
  38. *    these are vital parts of a normal full-sized application.
  39. *
  40. *    This application is an example of the form of a Macintosh 
  41. *    application; it is NOT a template. It is NOT intended to be 
  42. *    used as a foundation for the next world-class, best-selling, 
  43. *    600K application. A stick figure drawing of the human body may 
  44. *    be a good example of the form for a painting, but that does not 
  45. *    mean it should be used as the basis for the next Mona Lisa.
  46. *
  47. *    We recommend that you review this program or TESample before 
  48. *    beginning a new application.
  49.  
  50. * ================================================
  51. * -------------- INCLUDES SECTION ----------------
  52. * ================================================
  53.  
  54.     PRINT    PUSH,OFF                ; don't print any of this stuff
  55.  
  56.     INCLUDE 'Resources.a'
  57.     INCLUDE 'DiskInit.a'
  58.     INCLUDE 'Devices.a'
  59.     INCLUDE 'Processes.a'
  60.     INCLUDE 'Menus.a'
  61.     INCLUDE 'Memory.a'
  62.     INCLUDE 'LowMemEqu.a'
  63.     INCLUDE 'Dialogs.a'
  64.     INCLUDE 'Fonts.a'
  65.     INCLUDE 'Windows.a'
  66.     INCLUDE 'Traps.a'
  67.     INCLUDE    'Quickdraw.a'
  68.     INCLUDE 'Packages.a'
  69.     INCLUDE 'ToolUtils.a'
  70.  
  71.     INCLUDE    'Sample.inc1.a'            ; all our macros and data templates
  72.  
  73.     PRINT    POP                        ; restore the PRINT options
  74.  
  75.  
  76. * ================================================
  77. * -----------  DATA STORAGE USAGE  ---------------
  78. * ================================================
  79. * Here we will IMPORT the data that is being from the
  80. * DATA STORAGE ALLOCATION section of ASample.a.  By IMPORTing them
  81. * at this point, they will be accessible by this entire source file.
  82. * The symbol is IMPORTed and associated with the original template
  83. * as defined in the ASample.inc1.a file.  This allows us to use
  84. * the identifiers in the template.
  85.  
  86.         IMPORT    QD:QDGlobals
  87.         IMPORT    G:AppGlobals
  88.  
  89.  
  90. * ================================================
  91. * FUNCTION GoGetRect(rectID: INTEGER; VAR theRect: Rect) : BOOLEAN;
  92. * ================================================
  93. * This utility loads the global rectangles that are used by the window
  94. * drawing routines. It shows how the resource manager can be used to hold
  95. * values in a convenient manner. These values are then easily altered without
  96. * having to re-compile the source code. GoGetRect will return a BOOLEAN that
  97. * indicates if it was successful in getting the rectangle.
  98.  
  99. * A0 is being used for resource handle.
  100.  
  101.         SEG    'Initialize'                ; case sensitive
  102. GoGetRect    FUNC    EXPORT                ; any source file can use this routine
  103.  
  104. StackFrame    RECORD    {A6Link},DECR        ; build a stack frame record
  105. Result        DS.W    1                    ; function's result returned to caller
  106. ParamBegin    EQU    *                        ; start parameters after this point
  107. RectID        DS.W    1                    ; resource ID of rect passed by caller
  108. TheRect        DS.L    1                    ; the rect's pointer passed by caller
  109. ParamSize    EQU    ParamBegin-*            ; size of all the passed parameters
  110. RetAddr     DS.L    1                    ; place holder for return address
  111. A6Link        DS.L    1                    ; place holder for A6 link
  112. LocalSize    EQU     *                    ; size of all the local variables
  113.         ENDR
  114.  
  115.         WITH    StackFrame                ; cover our local stack frame
  116.         LINK    A6,#LocalSize            ; allocate our local stack frame
  117.  
  118.         MOVE.W    #False,Result(A6)        ; initialize function's result
  119.  
  120.         CLR.L    -(SP)                    ; create space for result
  121.         MOVE.L    #'RECT',-(SP)
  122.         MOVE.W    RectID(A6),-(SP)        ; get the stop light's rect
  123.         _GetResource
  124.         MOVEA.L    (SP)+,A0                ; handle to RECT resource in A0
  125.         CMPA.L    #0,A0                    ; test for NIL handle
  126.         BEQ.S    Exit                    ; didn't get resource, exit this procedure
  127.  
  128.  
  129. * -------- COPY THE RESOURCE TO THE RECT --------
  130.  
  131.         MOVE.W    #True100,Result(A6)                    ; we got the resource, return true
  132.         MOVEA.L    (A0),A0                                ; pointer to RECT resource in A0
  133.         MOVEA.L    TheRect(A6),A1                        ; pointer to the dest. RECT in A1
  134.         MOVE.L    Rect.topLeft(A0),Rect.topLeft(A1)    ; copy to the rect passed to us
  135.         MOVE.L    Rect.botRight(A0),Rect.botRight(A1)
  136.  
  137. Exit        UNLK    A6                    ; destroy the link
  138.         MOVEA.L    (SP)+,A0                ; pull off the return address
  139.         ADDA.L    #ParamSize,SP            ; strip all of the caller's parameters
  140.         JMP    (A0)                        ; return to the caller
  141.  
  142.         DbgInfo    GetRect                    ; this name will appear in the debugger
  143.         ENDF
  144.  
  145. * ================================================
  146. * FUNCTION IsDAWindow(window: WindowPtr): BOOLEAN;
  147. * ================================================
  148. * Check if a window belongs to a desk accessory.  DA window has a negitive kind.
  149.  
  150.         SEG    'Main'
  151. IsDAWindow    FUNC    EXPORT                ; any source file can use this routine
  152.  
  153. StackFrame    RECORD    {A6Link},DECR        ; build a stack frame record
  154. Result        DS.W    1                    ; function's result returned to caller
  155. ParamBegin    EQU    *                        ; start parameters after this point
  156. TheWindow    DS.L    1                    ; a window's pointer passed by caller
  157. ParamSize    EQU    ParamBegin-*            ; size of all the passed parameters
  158. RetAddr     DS.L    1                    ; place holder for return address
  159. A6Link        DS.L    1                    ; place holder for A6 link
  160. LocalSize    EQU     *                    ; size of all the local variables
  161.         ENDR
  162.  
  163.         WITH    StackFrame                ; cover our local stack frame
  164.         WITH    WindowRecord
  165.         LINK    A6,#LocalSize            ; allocate our local stack frame
  166.  
  167.         MOVE.W    #False,Result(A6)        ; first, initialize the result
  168.         CMPI.L    #0,TheWindow(A6)        ; valid pointer?
  169.         BEQ.S    Exit                    ; it was NIL, look out!
  170.  
  171.         MOVEA.L    TheWindow(A6),A0        ; get the window pointer
  172.         MOVE.W    WindowKind(A0),D0        ; what kind of window was it?
  173.         BPL.S    Exit                    ; DA windows are negitive
  174.  
  175.         MOVE.W    #True100,Result(A6)        ; return true to the caller
  176. Exit        UNLK    A6                    ; destroy the link
  177.         MOVEA.L    (SP)+,A0                ; pull off the return address
  178.         ADDA.L    #ParamSize,SP            ; strip all of the caller's parameters
  179.         JMP    (A0)                        ; return to the caller
  180.  
  181.         DbgInfo    IsDAWind                ; this name will appear in the debugger
  182.         ENDF
  183.  
  184. * ================================================
  185. * FUNCTION IsAppWindow(window: WindowPtr): BOOLEAN;
  186. * ================================================
  187. * Check to see if a window belongs to the application. If the window pointer
  188. * passed was NIL, then it could not be an application window. WindowKinds
  189. * that are negative belong to the system and windowKinds less than userKind
  190. * are reserved by Apple except for windowKinds equal to dialogKind, which
  191. * means it is a dialog.
  192. * In order to reduce the chance of accidentally treating some window
  193. * as an AppWindow that shouldn't be, we'll only return true if the windowkind
  194. * is userKind. If you add different kinds of windows to Sample you'll need
  195. * to change how this all works.
  196.  
  197.         SEG    'Main'
  198. IsAppWindow    FUNC    EXPORT                ; any source file can use this routine
  199.  
  200. StackFrame    RECORD    {A6Link},DECR        ; build a stack frame record
  201. Result        DS.W    1                    ; function's result returned to caller
  202. ParamBegin    EQU    *                        ; start parameters after this point
  203. TheWindow    DS.L    1                    ; a window's pointer passed by caller
  204. ParamSize    EQU    ParamBegin-*            ; size of all the passed parameters
  205. RetAddr     DS.L    1                    ; place holder for return address
  206. A6Link        DS.L    1                    ; place holder for A6 link
  207. LocalSize    EQU     *                    ; size of all the local variables
  208.         ENDR
  209.  
  210.         WITH    StackFrame                ; cover our local stack frame
  211.         WITH    WindowRecord
  212.         LINK    A6,#LocalSize            ; allocate our local stack frame
  213.  
  214.         MOVE.W    #False,Result(A6)        ; first, initialize the result
  215.         CMPI.L    #0,TheWindow(A6)        ; valid pointer?
  216.         BEQ.S    Exit                    ; it was NIL, look out!
  217.  
  218.         MOVEA.L    TheWindow(A6),A0        ; get the window pointer
  219.         MOVE.W    WindowKind(A0),D0        ; what kind of window was it?
  220.         CMPI.W    #UserKind,D0            ; was it an application window?
  221.         BNE.S    Exit                    ; no, result is going to be false
  222.  
  223.         MOVE.W    #True100,Result(A6)        ; return true to the caller
  224.  
  225. Exit        UNLK    A6                    ; destroy the link
  226.         MOVEA.L    (SP)+,A0                ; pull off the return address
  227.         ADDA.L    #ParamSize,SP            ; strip all of the caller's parameters
  228.         JMP    (A0)                        ; return to the caller
  229.  
  230.         DbgInfo    IsAppWin                ; this name will appear in the debugger
  231.         ENDF
  232.  
  233. * ================================================
  234. * PROCEDURE AlertUser;
  235. * ================================================
  236. * Display an alert that tells the user an error occurred, then exit the program.
  237. * This routine is used as an ultimate bail-out for serious errors that prohibit
  238. * the continuation of the application. Errors that do not require the termination
  239. * of the application should be handled in a different manner. Error checking and
  240. * reporting has a place even in the simplest application. For simplicity, the alert
  241. * displayed here only says that an error occurred, but not what it was. There are
  242. * various methods available for being more specific.
  243.  
  244.         SEG    'Main'                        ; case sensitive
  245. AlertUser    PROC    EXPORT                ; any source file can use this routine
  246.  
  247. StackFrame    RECORD    {A6Link},DECR        ; build a stack frame record
  248. ParamBegin    EQU    *                        ; start parameters after this point
  249. ParamSize    EQU    ParamBegin-*            ; size of all the passed parameters
  250. RetAddr     DS.L    1                    ; place holder for return address
  251. A6Link        DS.L    1                    ; place holder for A6 link
  252. LocalSize    EQU     *                    ; size of all the local variables
  253.         ENDR
  254.  
  255.         WITH    StackFrame                ; cover our local stack frame
  256.         LINK    A6,#LocalSize            ; allocate our local stack frame
  257.  
  258.         CLR.W    -(SP)                    ; space for result of Alert
  259.         MOVE.W    #rUserAlert,-(SP)        ; resource for alert dialog
  260.         CLR.L    -(SP)                    ; no filter procedure used here
  261.         _Alert                            ; read the resource and display it
  262.         MOVE.W    (SP)+,D0                ; I don't care which item is was
  263.         _ExitToShell                    ; we're out of here, no error recovery
  264.  
  265. Exit        UNLK    A6                    ; destroy the link
  266.         MOVEA.L    (SP)+,A0                ; pull off the return address
  267.         ADDA.L    #ParamSize,SP            ; strip all of the caller's parameters
  268.         JMP    (A0)                        ; return to the caller
  269.  
  270.         DbgInfo    AlrtUser                ; this name will appear in the debugger
  271.         ENDP
  272.  
  273. * ================================================
  274. * FUNCTION DoCloseWindow(window: WindowPtr) : BOOLEAN;
  275. * ================================================
  276. * At this point, if there was a document associated with a window, you could
  277. * do any document saving processing if it is 'dirty'.  DoCloseWindow would
  278. * return TRUE if the window actually closes, i.e., the user does not cancel
  279. * from a save dialog. This result is handy when the user quits an application,
  280. * but then cancels a save of a document associated with a window. We also added
  281. * code to close the application window since otherwise, the termination routines
  282. * would never stop looping, waiting for FrontWindow to return NIL.
  283.  
  284.          SEG    'Main'                        ; case sensitive
  285. DoCloseWindow    FUNC    EXPORT            ; any source file can use this routine
  286.  
  287. StackFrame    RECORD    {A6Link},DECR        ; build a stack frame record
  288. Result        DS.W    1                    ; function's result returned to caller
  289. ParamBegin    EQU    *                        ; start parameters after this point
  290. WindowPtr    DS.L    1                    ; passed window pointer parameter
  291. ParamSize    EQU    ParamBegin-*            ; size of all the passed parameters
  292. RetAddr     DS.L    1                    ; place holder for return address
  293. A6Link        DS.L    1                    ; place holder for A6 link
  294. LocalSize    EQU     *                    ; size of all the local variables
  295.         ENDR
  296.  
  297.         WITH    StackFrame                ; cover our local stack frame
  298.         WITH    WindowRecord
  299.         LINK    A6,#LocalSize            ; allocate our local stack frame
  300.  
  301.         MOVE.W    #True100,Result(A6);    ; initialize the function's result
  302.  
  303.         CLR.W    -(SP)                    ; space for result of IsDAWindow
  304.         MOVE.L    WindowPtr(A6),-(SP)        ; pass the window pointer
  305.         BSR    IsDAWindow
  306.         MOVE.W    (SP)+,D0                ; result of IsDAWindow
  307.         CMPI.W    #True100,D0
  308.         BNE.S    @1                        ; this wasn't a DA window
  309.  
  310.         MOVEA.L    WindowPtr(A6),A0        ; get window pointer
  311.         MOVE.W    WindowKind(A0),-(SP)    ; pass the refNum of DA
  312.         _CloseDeskAcc
  313.         BRA.S    Exit                    ; all done
  314.  
  315. @1        CLR.W    -(SP)                    ; space for result of IsAppWindow
  316.         MOVE.L    WindowPtr(A6),-(SP)        ; pass a the window pointer
  317.         BSR    IsAppWindow
  318.         MOVE.W    (SP)+,D0                ; result of IsAppWindow
  319.         CMPI.W    #True100,D0
  320.         BNE.S    Exit                    ; it wasn't our application's window
  321.  
  322.         MOVE.L    WindowPtr(A6),-(SP)        ; close window, it shouldn't be a dialog
  323.         _CloseWindow                    ; close the application window
  324.  
  325. Exit        UNLK    A6                    ; destroy the link
  326.         MOVEA.L    (SP)+,A0                ; pull off the return address
  327.         ADDA.L    #ParamSize,SP            ; strip all of the caller's parameters
  328.         JMP    (A0)                        ; return to the caller
  329.  
  330.         DbgInfo    ClosWind                ; this name will appear in the debugger
  331.         ENDF
  332.  
  333. * ================================================
  334. * PROCEDURE Terminate;
  335. * ================================================
  336. * Clean up the application and exit. We close all of the windows so that
  337. * they can update their documents, if any.  We don't have much to do here.
  338. * Just close our windows and then exit.  If we find out that a Cancel has
  339. * occurred (DoCloseWindow will return False) we won't exit to the shell,
  340. * but will simply exit this procedure.
  341.  
  342.         SEG    'Main'                        ; case sensitive
  343. Terminate    PROC    EXPORT
  344.  
  345. StackFrame    RECORD    {A6Link},DECR        ; build a stack frame record
  346. ParamBegin    EQU    *                        ; start parameters after this point
  347. ParamSize    EQU    ParamBegin-*            ; size of all the passed parameters
  348. RetAddr     DS.L    1                    ; place holder for return address
  349. A6Link        DS.L    1                    ; place holder for A6 link
  350. WindowPtr    DS.L    1                    ; local variable for a window pointer
  351. Closed        DS.W    1                    ; local variable for looping
  352. LocalSize    EQU     *                    ; size of all the local variables
  353.         ENDR
  354.  
  355.         IMPORT    DoCloseWindow
  356.  
  357.         WITH    StackFrame                ; cover our local stack frame
  358.         LINK    A6,#LocalSize            ; allocate our local stack frame
  359.  
  360.         MOVE.W    #True100,Closed(A6)        ; initialize local variable
  361.  
  362. Loop        CLR.L    -(SP)                ; space for front window pointer
  363.         _FrontWindow
  364.         MOVE.L    (SP)+,WindowPtr(A6)        ; get the front window pointer
  365.         CMPI.L    #0,WindowPtr(A6)        ; is there a front window?
  366.         BEQ.S    @1                        ; there are no more windows
  367.  
  368.         CLR.W    -(SP)                    ; space for result of DoCloseWindow
  369.         MOVE.L    WindowPtr(A6),-(SP)        ; pass the window pointer
  370.         BSR    DoCloseWindow                ; close all our windows
  371.         MOVE.W    (SP)+,Closed(A6)        ; get result of DoCloseWindow
  372.         CMPI.W    #True100,Closed(A6)        ; what's the result of DoCloseWindow?
  373.         BNE.S    Exit                    ; user didn't want to close that window
  374.  
  375.         BRA.S    Loop                    ; loop again and close the next window
  376.  
  377. @1        CMPI.W    #True100,Closed(A6)        ; should we really terminate?
  378.         BNE.S    Exit                    ; no, exit this procedure
  379.  
  380.         _ExitToShell                    ; we're done, let's get out of here
  381.  
  382. Exit        UNLK    A6                    ; destroy the link
  383.         MOVEA.L    (SP)+,A0                ; pull off the return address
  384.         ADDA.L    #ParamSize,SP            ; strip all of the caller's parameters
  385.         JMP    (A0)                        ; return to the caller
  386.  
  387.         DbgInfo    Terminat                ; this name will appear in the debugger
  388.         ENDP
  389.  
  390. * ================================================
  391. * PROCEDURE SetLight(window: WindowPtr; newStopped: BOOLEAN);
  392. * ================================================
  393. * Change the setting of the light and force an update event.
  394. * newStopped is the state of the stop light the user is requesting.
  395.  
  396.         SEG    'Main'                        ; case sensitive
  397. SetLight    PROC    EXPORT                ; any source file can use this routine
  398.  
  399. StackFrame    RECORD    {A6Link},DECR        ; build a stack frame record
  400. ParamBegin    EQU    *                        ; start parameters after this point
  401. WindowPtr    DS.L    1                    ; passed parameter of the window pointer
  402. newStopped    DS.W    1                    ; test value passed by caller
  403. ParamSize    EQU    ParamBegin-*            ; size of all the passed parameters
  404. RetAddr     DS.L    1                    ; place holder for return address
  405. A6Link        DS.L    1                    ; place holder for A6 link
  406. LocalSize    EQU     *                    ; size of all the local variables
  407.         ENDR
  408.  
  409.         WITH    StackFrame                ; cover our local stack frame
  410.         LINK    A6,#LocalSize            ; allocate our local stack frame
  411.  
  412.         MOVE.W    G.Stopped,D0            ; get state of stop light
  413.         CMP.W    newStopped(A6),D0        ; compare to the new state
  414.         BEQ.S    Exit                    ; they're the same, stupid user!
  415.  
  416.         MOVE.W    newStopped(A6),G.Stopped     ; set global to the new state
  417.         MOVE.L    WindowPtr(A6),-(SP)
  418.         _SetPort                            ; set the port to us
  419.         MOVEA.L    WindowPtr(A6),A0            ; force update event for window
  420.         PEA        GrafPort.portRect(A0)        ; invalidate entire window
  421.         _InvalRect
  422.  
  423. Exit        UNLK    A6                    ; destroy the link
  424.         MOVEA.L    (SP)+,A0                ; pull off the return address
  425.         ADDA.L    #ParamSize,SP            ; strip all of the caller's parameters
  426.         JMP    (A0)                        ; return to the caller
  427.  
  428.         DbgInfo    SetLight                ; this name will appear in the debugger
  429.         ENDP
  430.  
  431. * ================================================
  432. * PROCEDURE AdjustMenus;
  433. * ================================================
  434. * Enable and disable menus based on the current state.  The user can only select
  435. * enabled menu items. We set up all the menu items before calling MenuSelect or
  436. * MenuKey, since these are the only times that a menu item can be selected. Note
  437. * that MenuSelect is also the only time the user will see menu items. This
  438. * approach to deciding what enable/disable state a menu item has the advantage
  439. * of concentrating all the decision making in one routine, as opposed to being
  440. * spread throughout the application.  Other application designs may take a
  441. * different approach that are just as valid.
  442.  
  443.         SEG    'Main'                        ; case sensitive
  444. AdjustMenus    PROC    EXPORT                ; any source file can use this routine
  445.  
  446. StackFrame    RECORD    {A6Link},DECR        ; build a stack frame record
  447. ParamBegin    EQU    *                        ; start parameters after this point
  448. ParamSize    EQU    ParamBegin-*            ; size of all the passed parameters
  449. RetAddr     DS.L    1                    ; place holder for return address
  450. A6Link        DS.L    1                    ; place holder for A6 link
  451. FrontMost    DS.L    1                    ; local copy of the front window
  452. Menu        DS.L    1                    ; local copy of the menu handle
  453. LocalSize    EQU     *                    ; size of all the local variables
  454.         ENDR
  455.  
  456.         WITH    StackFrame                ; cover our local stack frame
  457.         LINK    A6,#LocalSize            ; allocate our local stack frame
  458.  
  459.         CLR.L    -(SP)                    ; space for result
  460.         _FrontWindow
  461.         MOVE.L    (SP)+,FrontMost(A6)        ; save the front window
  462.  
  463. * ------------- ADJUST THE FILE MENU -------------
  464. AdjustFile
  465.         CLR.L    -(SP)                    ; space for result
  466.         MOVE.W    #FileMenu,-(SP)            ; get the File menu handle
  467.         _GetMenuHandle
  468.         MOVE.L    (SP)+,Menu(A6)            ; save the menu handle
  469.         CLR.W    -(SP)                    ; space for result
  470.         MOVE.L    FrontMost(A6),-(SP)
  471.         BSR    IsDAWindow
  472.         MOVE.W    (SP)+,D0                ; get the result of the function
  473.         CMPI.W    #True100,D0                ; was it the DA window?
  474.         BNE.S    @1                        ; no, then disable the close item
  475.  
  476.         MOVE.L    Menu(A6),-(SP)            ; it was an application window
  477.         MOVE.W    #CloseItem,-(SP)
  478.         _EnableItem                        ; enable the close for DAs only
  479.         BRA.S    AdjustEdit
  480.  
  481. @1        MOVE.L    Menu(A6),-(SP)            ; it was not a DA window
  482.         MOVE.W    #CloseItem,-(SP)
  483.         _DisableItem                    ; disable close for all others
  484.  
  485. * ------------- ADJUST THE EDIT MENU -------------
  486. AdjustEdit
  487.         CLR.L    -(SP)                    ; space for result
  488.         MOVE.W    #EditMenu,-(SP)            ; get the Edit menu handle
  489.         _GetMenuHandle
  490.         MOVE.L    (SP)+,Menu(A6)            ; save the menu handle
  491.         CLR.W    -(SP)                    ; space for result
  492.         MOVE.L    FrontMost(A6),-(SP)
  493.         BSR    IsDAWindow
  494.         MOVE.W    (SP)+,D0                ; get the result of the function
  495.         CMPI.W    #True100,D0                ; was it the DA window?
  496.         BNE.S    @2                        ; no, disable the edit menu
  497.  
  498.         MOVE.L    Menu(A6),-(SP)            ; it was for a DA window
  499.         MOVE.W    #CutItem,-(SP)
  500.         _EnableItem                        ; enable the Cut
  501.         MOVE.L    Menu(A6),-(SP)
  502.         MOVE.W    #CopyItem,-(SP)
  503.         _EnableItem                        ; enable the Copy
  504.         MOVE.L    Menu(A6),-(SP)
  505.         MOVE.W    #PasteItem,-(SP)
  506.         _EnableItem                        ; enable the Paste
  507.         MOVE.L    Menu(A6),-(SP)
  508.         MOVE.W    #ClearItem,-(SP)
  509.         _EnableItem                        ; enable the Clear
  510.         BRA.S    AdjustLight                ; done with the edit menu
  511.  
  512. @2        MOVE.L    Menu(A6),-(SP)            ; disable the edit menu
  513.         MOVE.W    #UndoItem,-(SP)
  514.         _DisableItem                    ; disable the Undo
  515.         MOVE.L    Menu(A6),-(SP)
  516.         MOVE.W    #CutItem,-(SP)
  517.         _DisableItem                    ; disable the Cut
  518.         MOVE.L    Menu(A6),-(SP)
  519.         MOVE.W    #CopyItem,-(SP)
  520.         _DisableItem                    ; disable the Copy
  521.         MOVE.L    Menu(A6),-(SP)
  522.         MOVE.W    #PasteItem,-(SP)
  523.         _DisableItem                    ; disable the Paste
  524.         MOVE.L    Menu(A6),-(SP)
  525.         MOVE.W    #ClearItem,-(SP)
  526.         _DisableItem                    ; disable the Clear
  527.  
  528. * ------------- ADJUST THE LIGHT MENU -------------
  529. AdjustLight
  530.         CLR.L    -(SP)                    ; space for result
  531.         MOVE.W    #LightMenu,-(SP)        ; get the Edit menu handle
  532.         _GetMenuHandle
  533.         MOVE.L    (SP)+,Menu(A6)            ; save the menu handle
  534.         CLR.W    -(SP)                    ; space for result
  535.         MOVE.L    FrontMost(A6),-(SP)        ; the front window
  536.         BSR    IsAppWindow
  537.         MOVE.W    (SP)+,D3                ; save the result of the function
  538.         CMPI.W    #True100,D3                ; was our window in front?
  539.         BNE.S    @3                        ; no, disable the menu items
  540.  
  541.         MOVE.L    Menu(A6),-(SP)            ; enable the light menu
  542.         MOVE.W    #StopItem,-(SP)
  543.         _EnableItem                        ; enable the stop
  544.         MOVE.L    Menu(A6),-(SP)
  545.         MOVE.W    #GoItem,-(SP)
  546.         _EnableItem                        ; enable the go for our window
  547.         BRA.S    @4                        ; now check the menu items
  548.  
  549. @3        MOVE.L    Menu(A6),-(SP)            ; disable the light menu
  550.         MOVE.W    #StopItem,-(SP)
  551.         _DisableItem                    ; disable the stop
  552.         MOVE.L    Menu(A6),-(SP)
  553.         MOVE.W    #GoItem,-(SP)
  554.         _DisableItem                    ; disable the go
  555.         BRA.S    Exit                    ; nothing to check, get out of here
  556.  
  557. @4        MOVE.W    G.Stopped,D0            ; get the current state of the light
  558.         CMPI.W    #True100,D0                ; is the stop light on?
  559.         BNE.S    @5                        ; no, the green light is on
  560.  
  561.         MOVE.L    Menu(A6),-(SP)            ; set menu to red light = on
  562.         MOVE.W    #StopItem,-(SP)
  563.         MOVE.W    #True100,-(SP)
  564.         _CheckItem                        ; check the StopItem in the menu
  565.         MOVE.L    Menu(A6),-(SP)
  566.         MOVE.W    #GoItem,-(SP)
  567.         MOVE.W    #False,-(SP)
  568.         _CheckItem                        ; un-check the GoItem in the menu
  569.         BRA.S    Exit                    ; now we're done, get out of here
  570.  
  571. @5        MOVE.L    Menu(A6),-(SP)            ; set menu to green light = on
  572.         MOVE.W    #StopItem,-(SP)        
  573.         MOVE.W    #False,-(SP)
  574.         _CheckItem                        ; un-check the StopItem in the menu
  575.         MOVE.L    Menu(A6),-(SP)
  576.         MOVE.W    #GoItem,-(SP)
  577.         MOVE.W    #True100,-(SP)
  578.         _CheckItem                        ; check the GoItem in the menu
  579.  
  580. Exit        UNLK    A6                    ; destroy the link
  581.         MOVEA.L    (SP)+,A0                ; pull off the return address
  582.         ADDA.L    #ParamSize,SP            ; strip all of the caller's parameters
  583.         JMP    (A0)                        ; return to the caller
  584.  
  585.         DbgInfo    AdjstMnu                ; this name will appear in the debugger
  586.         ENDP
  587.  
  588. * ================================================
  589. * PROCEDURE DrawWindow(window: WindowPtr);
  590. * ================================================
  591. * Draw the contents of the application's window. We do some drawing in color,
  592. * using Classic QuickDraw's color capabilities. This will be black and white on
  593. * old machines, but color on color machines. The window's visRgn has been set by
  594. * the Update routine to cause drawing only where it needs to be done.
  595.  
  596.         SEG    'Main'                        ; case sensitive
  597. DrawWindow    PROC    EXPORT                ; any source file can use this routine
  598.  
  599. StackFrame    RECORD    {A6Link},DECR        ; build a stack frame record
  600. ParamBegin    EQU    *                        ; start parameters after this point
  601. WindowPtr    DS.L    1                    ; passed parameter of the window pointer
  602. ParamSize    EQU    ParamBegin-*            ; size of all the passed parameters
  603. RetAddr     DS.L    1                    ; place holder for return address
  604. A6Link        DS.L    1                    ; place holder for A6 link
  605. LocalSize    EQU     *                    ; size of all the local variables
  606.         ENDR
  607.  
  608.         WITH    StackFrame                ; cover our local stack frame
  609.         LINK    A6,#LocalSize            ; allocate our local stack frame
  610.  
  611.         MOVE.L    WindowPtr(A6),-(SP)
  612.         _SetPort                        ; set the current port to us
  613.         MOVEA.L    WindowPtr(A6),A0        ; erase the entire window
  614.         PEA    GrafPort.portRect(A0)        ; the window's rect
  615.         _EraseRect                        ; clear out anything remaining
  616.         MOVE.W    G.Stopped,D0            ; find the state of the lights
  617.         CMPI.W    #True100,D0
  618.         BNE.S    @1                        ; red light should be off
  619.  
  620. * ------------- RED LIGHT -------------
  621.  
  622.         MOVE.L    #redColor,-(SP)            ; make the red light go on
  623.         _ForeColor
  624.         PEA    G.StopRect
  625.         _PaintOval
  626.         MOVE.L    #whiteColor,-(SP)        ; make the green light go off
  627.         _ForeColor    
  628.         PEA    G.GoRect
  629.         _PaintOval
  630.         BRA.S    @2
  631.  
  632. * ------------- GREEN LIGHT -------------
  633.  
  634. @1        MOVE.L    #greenColor,-(SP)        ; make the green light go on
  635.         _ForeColor    
  636.         PEA    G.GoRect
  637.         _PaintOval
  638.         MOVE.L    #whiteColor,-(SP)        ; make the red light go off
  639.         _ForeColor
  640.         PEA    G.StopRect
  641.         _PaintOval
  642.  
  643. * ------------- FRAME THE LIGHTS -------------
  644.  
  645. @2        MOVE.L    #blackColor,-(SP)
  646.         _ForeColor
  647.         PEA    G.StopRect
  648.         _FrameOval                        ; draw black line around light
  649.         PEA    G.GoRect
  650.         _FrameOval                        ; draw black line around light
  651.  
  652. Exit        UNLK    A6                    ; destroy the link
  653.         MOVEA.L    (SP)+,A0                ; pull off the return address
  654.         ADDA.L    #ParamSize,SP            ; strip all of the caller's parameters
  655.         JMP    (A0)                        ; return to the caller
  656.  
  657.         DbgInfo    DrawWind                ; this name will appear in the debugger
  658.         ENDP
  659.  
  660. * ================================================
  661. * PROCEDURE GetGlobalMouse(VAR mouse: Point);
  662. * ================================================
  663. * Get the global coordinates of the mouse. When you call OSEventAvail
  664. * it will return either a pending event or a null event. In either case,
  665. * the where field of the event record will contain the current position
  666. * of the mouse in global coordinates and the modifiers field will reflect
  667. * the current state of the modifiers. Another way to get the global
  668. * coordinates is to call GetMouse and LocalToGlobal, but that requires
  669. * being sure that thePort is set to a valid port.}
  670.  
  671.         SEG    'Main'                        ; case sensitive
  672. GetGlobalMouse    PROC    EXPORT            ; any source file can use this routine
  673.  
  674. StackFrame    RECORD    {A6Link},DECR        ; build a stack frame record
  675. ParamBegin    EQU    *                        ; start parameters after this point
  676. Mouse        DS.L    1                    ; passed reference to mouse position
  677. ParamSize    EQU    ParamBegin-*            ; size of all the passed parameters
  678. RetAddr     DS.L    1                    ; place holder for return address
  679. A6Link        DS.L    1                    ; place holder for A6 link
  680. TheEvent     DS    EventRecord             ; local copy of the event record
  681. LocalSize    EQU     *                    ; size of all the local variables
  682.         ENDR
  683.  
  684.         WITH    StackFrame                ; cover our local stack frame
  685.         LINK    A6,#LocalSize            ; allocate our local stack frame
  686.     
  687.         MOVE.W    #NoEvents,D0            ; we aren't interested in any events
  688.         LEA    TheEvent(A6),A0                ; point to event record
  689.         _OSEventAvail                    ; just the mouse position
  690.         MOVE.L    Mouse(A6),A0            ; deref address of mouse
  691.         MOVE.L    TheEvent.Where(A6),(A0)    ; stuff new value
  692.  
  693.         UNLK    A6                        ; destroy the link
  694.         MOVEA.L    (SP)+,A0                ; pull off the return address
  695.         ADDA.L    #ParamSize,SP            ; strip all of the caller's parameters
  696.         JMP    (A0)                        ; return to the caller
  697.  
  698.         DbgInfo    GetGlobalMouse            ; this name will appear in the debugger
  699.         ENDP
  700.  
  701. * ================================================
  702. * PROCEDURE AdjustCursor(mouse: Point; region: RgnHandle);
  703. * ================================================
  704. * Change the cursor's shape, depending on its position. This also calculates the
  705. * region where the current cursor resides (for WaitNextEvent). If the mouse is
  706. * ever outside of that region, an event would be generated, causing this routine
  707. * to be called, allowing us to change the region to the region the mouse is
  708. * currently in. If there is more to the event than just the mouse moved, we
  709. * get called before the event is processed to make sure the cursor is the right
  710. * one. In any (ahem) event, this is called again before we fall back into WNE.
  711. * 1.02 - Removed the mouse position parameter and instead use the current position
  712. * of the mouse by calling GetMouse and LocalToGlobal.
  713.  
  714.         SEG    'Main'                        ; case sensitive
  715. AdjustCursor    PROC    EXPORT
  716.  
  717. StackFrame    RECORD    {A6Link},DECR        ; build a stack frame record
  718. ParamBegin    EQU    *                        ; start parameters after this point
  719. Where        DS.L    1                    ; the mouse location passed to us
  720. MouseRegion    DS.L    1                    ; passed pointer to current region
  721. ParamSize    EQU    ParamBegin-*            ; size of all the passed parameters
  722. RetAddr     DS.L    1                    ; place holder for return address
  723. A6Link        DS.L    1                    ; place holder for A6 link
  724. FrontMost    DS.L    1                    ; local pointer to the front window
  725. ArrowRgn    DS.L    1                    ; local handle to the arrow cursor region
  726. PlusRgn        DS.L    1                    ; local handle to the plus cursor region
  727. LocalSize    EQU     *                    ; size of all the local variables
  728.         ENDR        
  729.  
  730.         IMPORT    IsDAWindow,IsAppWindow
  731.  
  732.         WITH    StackFrame                ; cover our local stack frame
  733.         LINK    A6,#LocalSize            ; allocate our local stack frame
  734.  
  735.         CLR.W    -(SP)                    ; space for result of IsAppWindow
  736.         CLR.L    -(SP)                    ; space for result of FrontWindow
  737.         _FrontWindow                    ; push front window pointer
  738.         MOVE.L    (SP),FrontMost(A6)        ; copy pointer and keep it on stack
  739.         BSR    IsDAWindow                    ; is this an application window?
  740.         MOVE.W    (SP)+,D0
  741.         CMPI.W    #True100,D0
  742.         BEQ.W    Exit                    ; not our window, don't adjust the cursor
  743.         CMPI.W    #True100,G.InBackground
  744.         BEQ.W    Exit                    ; and do nothing if we're in the background
  745.  
  746. * ------------- INITIALIZE SOME REGION DATA -------------
  747.  
  748.         CLR.L    -(SP)
  749.         _NewRgn                            ; create an empty plus region
  750.         MOVE.L    (SP)+,PlusRgn(A6)
  751.         CLR.L    -(SP)
  752.         _NewRgn                            ; create an empty arrow region
  753.         MOVE.L    (SP)+,ArrowRgn(A6)
  754.         MOVE.L    ArrowRgn(A6),-(SP)        ; arrow region handle
  755.         MOVE.W    #ExtremeNeg,-(SP)        ; big left corner
  756.         MOVE.W    #ExtremeNeg,-(SP)        ; big top corner
  757.         MOVE.W    #ExtremePos,-(SP)        ; big right corner
  758.         MOVE.W    #ExtremePos,-(SP)        ; big bottom corner
  759.         _SetRectRgn                        ; really big rectangular region
  760.  
  761.         CLR.W    -(SP)
  762.         MOVE.L    FrontMost(A6),-(SP)
  763.         BSR    IsAppWindow                    ; is this an application window?
  764.         MOVE.W    (SP)+,D0
  765.         CMPI.W    #True100,D0
  766.         BNE.S    @1                        ; our window isn't in front?
  767.  
  768. * ------------- CALCULATE THE PLUS REGION -------------
  769.  
  770.         MOVE.L    FrontMost(A6),-(SP)
  771.         _SetPort                                        ; set the current port to us
  772.         MOVEA.L    FrontMost(A6),A0
  773.         MOVE.W    GrafPort.portBits.bounds.left(A0),D0
  774.         NEG.W    D0                                        ; offset window's left edge...
  775.         MOVE.W    D0,-(SP)                                ; to the screen's left edge
  776.         MOVEA.L    FrontMost(A6),A0
  777.         MOVE.W    GrafPort.portBits.bounds.top(A0),D0
  778.         NEG.W    D0                                        ; offset window's top edge...
  779.         MOVE.W    D0,-(SP)                                ; to the screen's top edge
  780.         _SetOrigin                                        ; make window rect global
  781.         MOVE.L    PlusRgn(A6),-(SP)                        ; handle to empty plus region
  782.         MOVEA.L    FrontMost(A6),A0                        ; pointer to our window
  783.         PEA    GrafPort.portRect(A0)                        ; window rect's global coordinates
  784.         _RectRgn                                        ; make global window rect into region
  785.         MOVE.L    PlusRgn(A6),-(SP)                        ; get intersection of plus and window region
  786.         MOVEA.L    FrontMost(A6),A0
  787.         MOVE.L    GrafPort.visRgn(A0),-(SP)                ; get front window's visRgn
  788.         MOVE.L    PlusRgn(A6),-(SP)                        ; resulting region will be in PlusRgn
  789.         _SectRgn                                        ; intersection the two regions
  790.         CLR.L    -(SP)                                    ; reset the origin of our window to 0,0
  791.         _SetOrigin
  792.  
  793. @1        MOVE.L    ArrowRgn(A6),-(SP)            ; the really big rectangular region
  794.         MOVE.L    PlusRgn(A6),-(SP)            ; the region of our window
  795.         MOVE.L    ArrowRgn(A6),-(SP)            ; intersetion of the Arrow and Plus region
  796.         _DiffRgn                            ; this is the region where the Arrow shows
  797.         CLR.W    -(SP)                        ; space for result of PtInRect
  798.         MOVE.L    Where(A6),-(SP)                ; here's the mouse
  799.         MOVE.L    PlusRgn(A6),-(SP)            ; where the arrow should show up
  800.         _PtInRgn                            ; was cursor in the arrow region?
  801.         MOVE.W    (SP)+,D0
  802.         CMPI.W    #True100,D0
  803.         BNE.S    @2                            ; cursor was in arrow region
  804.  
  805. * ------------- SET THE CURSOR AND NEW MOUSE REGION -------------
  806.  
  807.         CLR.L    -(SP)                        ; space for result
  808.         MOVE.W    #plusCursor,-(SP)            ; I want the plus cursor now!
  809.         _GetCursor
  810.         MOVEA.L    (SP)+,A0                    ; get the handle
  811.         CMPA.L    #0,A0
  812.         BEQ.S    Exit                        ; check for NIL like a good boy
  813.         MOVE.L    (A0),-(SP)                    ; got the plus cursor
  814.         _SetCursor                            ; set cursor to plus
  815.         MOVE.L    PlusRgn(A6),-(SP)            ; current region containing cursor
  816.         MOVE.L    MouseRegion(A6),-(SP)        ; set it to the new region
  817.         _CopyRgn
  818.         BRA.S    @3                            ; we're done, get out of here
  819.  
  820. @2        PEA    QD.Arrow                        ; got arrow cursor at InitGraf
  821.         _SetCursor                            ; set cursor to the Arrow
  822.         MOVE.L    ArrowRgn(A6),-(SP)            ; current region containing cursor
  823.         MOVE.L    MouseRegion(A6),-(SP)        ; set it to the new region
  824.         _CopyRgn
  825.  
  826. @3        MOVE.L    PlusRgn(A6),-(SP)            ; dispose of our two temporary regions
  827.         _DisposeRgn
  828.         MOVE.L    ArrowRgn(A6),-(SP)
  829.         _DisposeRgn
  830.  
  831. Exit        UNLK    A6                        ; destroy the link
  832.         MOVEA.L    (SP)+,A0                    ; pull off the return address
  833.         ADDA.L    #ParamSize,SP                ; strip all of the caller's parameters
  834.         JMP    (A0)                            ; return to the caller
  835.         
  836.         DbgInfo    AdjstCur                    ; this name will appear in the debugger
  837.         ENDP
  838.  
  839.         END                                    ; end of this source file
  840.